<!-- 此组件未使用 -->
<template>
  <div class="goDemo">
    <div id="myDiagramDiv" style="width:100%; height:100vh; background-color: #ECA;"></div>
  </div>
</template>

<script>
import go from "gojs";
export default {
  mounted() {
    // Use a TreeNode so that when a node is not visible because a parent is collapsed,
    // connected links seem to be connected with the lowest visible parent node.
    // This also forces other links connecting with nodes in the group to be rerouted,
    // because collapsing/expanding nodes will cause many nodes to move and to appear or disappear.
    function TreeNode() {
      go.Node.call(this);
      this.treeExpandedChanged = function(node) {
        if (node.containingGroup !== null) {
          node.containingGroup.findExternalLinksConnected().each(function(l) {
            l.invalidateRoute();
          });
        }
      };
    }
    go.Diagram.inherit(TreeNode, go.Node);

    TreeNode.prototype.findVisibleNode = function() {
      // redirect links to lowest visible "ancestor" in the tree
      var n = this;
      while (n !== null && !n.isVisible()) {
        n = n.findTreeParentNode();
      }
      return n;
    };
    // end TreeNode

    // Control how Mapping links are routed:
    // - "Normal": normal routing with fixed fromEndSegmentLength & toEndSegmentLength
    // - "ToGroup": so that the link routes stop at the edge of the group,
    //     rather than going all the way to the connected nodes
    // - "ToNode": so that they go all the way to the connected nodes
    //     but only bend at the edge of the group
    var ROUTINGSTYLE = "ToGroup";

    // If you want the regular routing where the Link.[from/to]EndSegmentLength controls
    // the length of the horizontal segment adjacent to the port, don't use this class.
    // Replace MappingLink with a go.Link in the "Mapping" link template.
    function MappingLink() {
      go.Link.call(this);
    }
    go.Diagram.inherit(MappingLink, go.Link);

    MappingLink.prototype.getLinkPoint = function(
      node,
      port,
      spot,
      from,
      ortho,
      othernode,
      otherport
    ) {
      if (ROUTINGSTYLE !== "ToGroup") {
        return go.Link.prototype.getLinkPoint.call(
          this,
          node,
          port,
          spot,
          from,
          ortho,
          othernode,
          otherport
        );
      } else {
        var r = port.getDocumentBounds();
        var group = node.containingGroup;
        var b = group !== null ? group.actualBounds : node.actualBounds;
        var op = othernode.getDocumentPoint(go.Spot.Center);
        var x = op.x > r.centerX ? b.right : b.left;
        return new go.Point(x, r.centerY);
      }
    };

    MappingLink.prototype.computePoints = function() {
      var result = go.Link.prototype.computePoints.call(this);
      if (result && ROUTINGSTYLE === "ToNode") {
        var fn = this.fromNode;
        var tn = this.toNode;
        if (fn && tn) {
          var fg = fn.containingGroup;
          var fb = fg ? fg.actualBounds : fn.actualBounds;
          var fpt = this.getPoint(0);
          var tg = tn.containingGroup;
          var tb = tg ? tg.actualBounds : tn.actualBounds;
          var tpt = this.getPoint(this.pointsCount - 1);
          this.setPoint(
            1,
            new go.Point(fpt.x < tpt.x ? fb.right : fb.left, fpt.y)
          );
          this.setPoint(
            this.pointsCount - 2,
            new go.Point(fpt.x < tpt.x ? tb.left : tb.right, tpt.y)
          );
        }
      }
      return result;
    };
    // end MappingLink

    function init() {
      console.log("123");

      var mySelf = this;
      const MAKE = go.GraphObject.make;
      mySelf.myDiagram = MAKE(go.Diagram, "myDiagramDiv", {
        "commandHandler.copiesTree": true,
        "commandHandler.deletesTree": true,
        // newly drawn links always map a node in one tree to a node in another tree
        "linkingTool.archetypeLinkData": { category: "Mapping" },
        "linkingTool.linkValidation": checkLink,
        "relinkingTool.linkValidation": checkLink,
        "undoManager.isEnabled": true
      });

      // All links must go from a node inside the "Left Side" Group to a node inside the "Right Side" Group.
      function checkLink(fn, fp, tn, tp, link) {
        // make sure the nodes are inside different Groups
        if (fn.containingGroup === null || fn.containingGroup.data.key !== -1)
          return false;
        if (tn.containingGroup === null || tn.containingGroup.data.key !== -2)
          return false;
        //// optional limit to a single mapping link per node
        //if (fn.linksConnected.any(function(l) { return l.category === "Mapping"; })) return false;
        //if (tn.linksConnected.any(function(l) { return l.category === "Mapping"; })) return false;
        return true;
      }

      // Each node in a tree is defined using the default nodeTemplate.
      myDiagram.nodeTemplate = MAKE(
        TreeNode,
        { movable: false, copyable: false, deletable: false }, // user cannot move an individual node
        // no Adornment: instead change panel background color by binding to Node.isSelected
        {
          selectionAdorned: false,
          background: "white",
          mouseEnter: function(e, node) {
            node.background = "aquamarine";
          },
          mouseLeave: function(e, node) {
            node.background = node.isSelected ? "skyblue" : "white";
          }
        },
        new go.Binding("background", "isSelected", function(s) {
          return s ? "skyblue" : "white";
        }).ofObject(),
        // whether the user can start drawing a link from or to this node depends on which group it's in
        new go.Binding("fromLinkable", "group", function(k) {
          return k === -1;
        }),
        new go.Binding("toLinkable", "group", function(k) {
          return k === -2;
        }),
        MAKE(
          "TreeExpanderButton", // support expanding/collapsing subtrees
          {
            width: 14,
            height: 14,
            "ButtonIcon.stroke": "white",
            "ButtonIcon.strokeWidth": 2,
            "ButtonBorder.fill": "goldenrod",
            "ButtonBorder.stroke": null,
            "ButtonBorder.figure": "Rectangle",
            _buttonFillOver: "darkgoldenrod",
            _buttonStrokeOver: null,
            _buttonFillPressed: null
          }
        ),
        MAKE(
          go.Panel,
          "Horizontal",
          { position: new go.Point(16, 0) },
          //// optional icon for each tree node
          MAKE(
            go.Picture,
            {
              width: 14,
              height: 14,
              margin: new go.Margin(0, 20, 0, 0),
              imageStretch: go.GraphObject.Uniform,
              source: "/logo.png"
            },
            new go.Binding("source", "src")
          ),
          MAKE(
            go.TextBlock,
            new go.Binding("text", "key", function(s) {
              console.log(s);

              return "item " + s;
            })
          )
        ) // end Horizontal Panel
      ); // end Node

      // These are the links connecting tree nodes within each group.

      myDiagram.linkTemplate = MAKE(go.Link); // without lines

      myDiagram.linkTemplate = MAKE(
        // with lines
        go.Link,
        {
          selectable: false,
          routing: go.Link.Orthogonal,
          fromEndSegmentLength: 4,
          toEndSegmentLength: 4,
          fromSpot: new go.Spot(0.001, 1, 7, 0),
          toSpot: go.Spot.Left
        },
        MAKE(go.Shape, { stroke: "lightgray" })
      );

      // These are the blue links connecting a tree node on the left side with one on the right side.
      myDiagram.linkTemplateMap.add(
        "Mapping",
        MAKE(
          MappingLink,
          {
            isTreeLink: false,
            isLayoutPositioned: false,
            layerName: "Foreground"
          },
          { fromSpot: go.Spot.Right, toSpot: go.Spot.Left },
          { relinkableFrom: true, relinkableTo: true },
          MAKE(go.Shape, { stroke: "blue", strokeWidth: 2 })
        )
      );

      myDiagram.groupTemplate = MAKE(
        go.Group,
        "Auto",
        { deletable: false, layout: makeGroupLayout() },
        new go.Binding("position", "xy", go.Point.parse).makeTwoWay(
          go.Point.stringify
        ),
        new go.Binding("layout", "width", makeGroupLayout),
        MAKE(go.Shape, { fill: "white", stroke: "lightgray" }),
        MAKE(
          go.Panel,
          "Vertical",
          { defaultAlignment: go.Spot.Left },
          MAKE(
            go.TextBlock,
            { font: "bold 14pt sans-serif", margin: new go.Margin(5, 5, 0, 5) },
            new go.Binding("text")
          ),
          MAKE(go.Placeholder, { padding: 5 })
        )
      );

      function makeGroupLayout() {
        return MAKE(
          go.TreeLayout, // taken from samples/treeView.html
          {
            alignment: go.TreeLayout.AlignmentStart,
            angle: 0,
            compaction: go.TreeLayout.CompactionNone,
            layerSpacing: 16,
            layerSpacingParentOverlap: 1,
            nodeIndentPastParent: 1.0,
            nodeSpacing: 0,
            setsPortSpot: false,
            setsChildPortSpot: false,
            // after the tree layout, change the width of each node so that all
            // of the nodes have widths such that the collection has a given width
            commitNodes: function() {
              go.TreeLayout.prototype.commitNodes.call(this);
              if (ROUTINGSTYLE === "ToGroup") {
                updateNodeWidths(this.group, this.group.data.width || 100);
              }
            }
          }
        );
      }

      // Create some random trees in each group
      var nodeDataArray = [
        {
          isGroup: true,
          key: -1,
          text: "审计三部/年报",
          xy: "0 0",
          width: 150
        },
        { isGroup: true, key: -2, text: "百邦/年报", xy: "300 0", width: 150 }
      ];
      var linkDataArray = [
        // 连线规则
        {
          from: "业务活动程序表",
          to: "A1-200审计业务约定合同书（合同式）",
          category: "Mapping"
        }
        // { from: 4, to: 1006, category: "Mapping" },
        // { from: 9, to: 1004, category: "Mapping" },
        // { from: 1, to: 1009, category: "Mapping" },
        // { from: 14, to: 1010, category: "Mapping" }
      ];

      // initialize tree on left side
      var root = { key: 0, group: -1 };
      nodeDataArray.push(root);
      for (var i = 0; i < 11; ) {
        i = makeTree(
          3,
          i,
          17,
          nodeDataArray,
          linkDataArray,
          root,
          -1,
          root.key
        );
      }

      // initialize tree on right side
      root = { key: 1000, group: -2 };
      nodeDataArray.push(root);
      let arr = ["测试1", "测试ce", "你猜", "哈哈哈", "花花", "无聊"];
      for (var i = 0; i < arr.length; ) {
        i = makeTree(
          3,
          i,
          15,
          nodeDataArray,
          linkDataArray,
          root,
          -2,
          // root.key
          arr[i]
        );
      }
      myDiagram.model = new go.GraphLinksModel(nodeDataArray, linkDataArray);
    }

    // help create a random tree structure
    function makeTree(
      level,
      count,
      max,
      nodeDataArray,
      linkDataArray,
      parentdata,
      groupkey,
      rootkey
    ) {
      var numchildren = Math.floor(Math.random() * 10);
      for (var i = 0; i < numchildren; i++) {
        if (count >= max) return count;
        count++;
        var childdata = { key: rootkey + count, group: groupkey };
        nodeDataArray.push(childdata);
        linkDataArray.push({ from: parentdata.key, to: childdata.key });
        if (level > 0 && Math.random() > 0.5) {
          count = makeTree(
            level - 1,
            count,
            max,
            nodeDataArray,
            linkDataArray,
            childdata,
            groupkey,
            rootkey
          );
        }
      }
      return count;
    }
    window.addEventListener("DOMContentLoaded", init);

    function updateNodeWidths(group, width) {
      if (isNaN(width)) {
        group.memberParts.each(function(n) {
          if (n instanceof go.Node) n.width = NaN; // back to natural width
        });
      } else {
        var minx = Infinity; // figure out minimum group width
        group.memberParts.each(function(n) {
          if (n instanceof go.Node) {
            minx = Math.min(minx, n.actualBounds.x);
          }
        });
        if (minx === Infinity) return;
        var right = minx + width;
        group.memberParts.each(function(n) {
          if (n instanceof go.Node)
            n.width = Math.max(0, right - n.actualBounds.x);
        });
      }
    }

    // this function is only needed when changing the value of ROUTINGSTYLE dynamically
    function changeStyle() {
      // find user-chosen style name
      var stylename = "ToGroup";
      var radio = document.getElementsByName("MyRoutingStyle");
      for (var i = 0; i < radio.length; i++) {
        if (radio[i].checked) {
          stylename = radio[i].value;
          break;
        }
      }
      if (stylename !== ROUTINGSTYLE) {
        myDiagram.commit(function(diag) {
          ROUTINGSTYLE = stylename;
          diag.findTopLevelGroups().each(function(g) {
            updateNodeWidths(g, NaN);
          });
          diag.layoutDiagram(true); // force layouts to happen again
          diag.links.each(function(l) {
            l.invalidateRoute();
          });
        });
      }
    }
  }
};
</script>

<style>
.k{
  color: rgba(250,250,250,0.6);
}
</style>